import pandas as pd
import streamlit as st
import time

st.header("状态管理")

# 缓存修饰器
# @st.cache_data装饰器用于记忆函数的历史执行。
# 当使用@st.cache装饰一个函数时，Streamlit 会将该函数的结果存储在一个缓存中，以便在后续调用中直接返回缓存的结果，而不是重新计算。
# 这可以提高应用程序的性能，特别是在处理大量数据或计算密集型任务时。
#
# 参数如下：
#   func:要缓存的函数。如果提供了函数，则会对该函数的计算结果进行缓存。如果为None，则返回一个可以接受函数作为参数的装饰器。
#   ttl(int or None):必需。缓存的生存时间，以秒为单位。在缓存的生存时间内，对函数的调用将返回缓存的结果而不是重新计算。如果设置为None，缓存将永不过期。
#   max_entries(int or None):可选。缓存的最大条目数。当达到指定的最大条目数时，新的计算结果将替换最早的计算结果。
#   show_spinner(bool):可选。当进行缓存计算时，是否显示加载指示器。默认为True。
#   persist(bool):可选。是否将缓存数据持久化到磁盘。如果为True，数据将在应用程序重新启动时仍然存在。默认为False。
#   experimental_allow_widgets(bool):可选。是否允许在被缓存的函数中使用Streamlit小部件。默认为False。启用此选项时，可以在被缓存的函数中使用小部件。
#   hash_funcs(dictorNone):可选。用于指定自定义哈希函数的字典。键是参数名称，值是哈希函数。如果为None，将使用默认哈希函数。
st.subheader("---------- 缓存修饰器 ----------")


@st.cache_data
def fetch_data(url):
    time.sleep(5)
    return pd.read_csv(url)


url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/heart-disease/processed.cleveland.data'
d1 = fetch_data(url)
st.write(d1)

#  无需请求url,直接使用第一步的缓存数据
d2 = fetch_data(url)
st.write(d2)

# 清空缓存后，需要重新霍去病
st.cache_data.clear()

d3 = fetch_data(url)
st.write(d3)

# 会话状态管理
# 用于在用户的会话期间存储和访问状态。这对于需要跨页面或组件之间共享的数据特别有用。
# 应用场景：
#   用户登录状态：存储 logged_in 标记，控制页面权限
#   多步骤表单：在页面间传递用户输入（如 st.session_state.user_input）
#   购物车系统：实时更新商品数量与总价
st.subheader("---------- 会话状态管理 ----------")
import streamlit as st

# 初始化状态变量
if "counter" not in st.session_state:
    st.session_state.counter = 0  # 初始化[1](@ref)


# 动态更新
def increment_counter():
    st.session_state.counter += 1


st.button("状态增加", on_click=increment_counter)  # 触发状态更新[2](@ref)

# 多用户全局状态共享
# 适用于 跨会话同步数据 （如实时聊天室、协作看板）。
# pip install streamlit-server-state
st.subheader("---------- 多用户全局状态共享 ----------")


# 1. 核心机制
#   全局状态对象：server_state 存储共享数据，所有会话可见.
#   线程安全锁：server_state_lock 防止并发冲突.
from streamlit_server_state import server_state, server_state_lock, no_rerun

with server_state_lock["count"]:
    server_state.count += 1  # 安全更新[6,7](@ref)

# 2.自动同步与抑制
# 默认状态更新触发所有会话重载，可通过 no_rerun 上下文禁止
with no_rerun:
    server_state.count = 42  # 更新但不触发重载[7](@ref)


# 认证授权

# pip install streamlit-authenticator
# streamlit-authenticator ：是一个专门为 Streamlit 设计的简单认证库，它支持用户登录、注册以及基于角色的访问控制。

# pip install streamlit-oauth
# 对于需要 OAuth 认证的应用，可以考虑 streamlit-oauth 库，它可以帮助你集成 Google、GitHub 等 OAuth 提供商
st.subheader("---------- 认证授权 ----------")
